import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import os
import matplotlib as mpl
from datetime import datetime, timedelta
import calendar

# 设置中文字体支持
try:
    plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'WenQuanYi Micro Hei', 'STXihei']
    plt.rcParams['axes.unicode_minus'] = False
    print("中文支持已启用")
except:
    print("中文支持设置失败，将使用英文")

# 读取Excel文件
file_path = 'E:/M/MathModel/23国赛C题/ds/附件5.xlsx'
sale = pd.read_excel(file_path, sheet_name='合并')
print("数据读取成功！总记录数:", len(sale))

# 转换日期格式
sale['销售日期'] = pd.to_datetime(sale['销售日期'])

time_periods = [
    # 2020年11月（避开双十一购物节）
    {'year': 2020, 'month': 11, 'start_day': 16, 'end_day': 22, 'name': '2020年11月'},

    # 2021年8月（避开暑假高峰期）
    {'year': 2021, 'month': 8, 'start_day': 9, 'end_day': 15, 'name': '2021年8月'},

    # 2022年5月（避开劳动节假期）
    {'year': 2022, 'month': 5, 'start_day': 9, 'end_day': 15, 'name': '2022年5月'},

    # 2023年2月（避开春节和元宵节）
    {'year': 2023, 'month': 2, 'start_day': 6, 'end_day': 12, 'name': '2023年2月'}
]

# 创建图表
plt.figure(figsize=(18, 12))

# 分别画图
for i, period in enumerate(time_periods, 1):
    # 创建日期范围
    start_date = datetime(period['year'], period['month'], period['start_day'])
    end_date = datetime(period['year'], period['month'], period['end_day'])
    date_range = pd.date_range(start=start_date, end=end_date, freq='D')

    # 筛选当前时间段的数据
    period_data = sale[(sale['销售日期'] >= start_date) &
                       (sale['销售日期'] <= end_date)]

    # 按日期分组计算每日总销量
    daily_sales = period_data.groupby('销售日期')['销量(千克)'].sum().reset_index()

    # 确保所有日期都在数据中（填充缺失日期）
    daily_sales = daily_sales.set_index('销售日期').reindex(date_range).fillna(0).reset_index()
    daily_sales.columns = ['销售日期', '总销量(千克)']

    # 添加星期几列
    daily_sales['星期'] = daily_sales['销售日期'].dt.day_name()

    # 创建子图
    ax = plt.subplot(2, 2, i)

    # 绘制折线图
    ax.plot(daily_sales['销售日期'], daily_sales['总销量(千克)'],
            marker='o', linestyle='-', linewidth=2.5, markersize=8, color='#1f77b4')

    # 添加数据点标签
    for _, row in daily_sales.iterrows():
        ax.annotate(f'{row["总销量(千克)"]:.1f}',
                    (row['销售日期'], row['总销量(千克)']),
                    xytext=(0, 10),
                    textcoords='offset points',
                    ha='center',
                    fontsize=10)

    # 设置标题和标签
    ax.set_title(f'{period["name"]} {start_date.day}日到{end_date.day}日的销量趋势图', fontsize=14)
    ax.set_xlabel('日期', fontsize=12)
    ax.set_ylabel('销售量(千克)', fontsize=12)

    # 设置X轴日期格式
    ax.set_xticks(daily_sales['销售日期'])

    # 创建标签
    def format_date_label(date):
        return f"{date.day}日\n({['周一', '周二', '周三', '周四', '周五', '周六', '周日'][date.weekday()]})"


    labels = [format_date_label(d) for d in daily_sales['销售日期']]
    ax.set_xticklabels(labels, fontsize=10)

    # 添加网格线
    ax.grid(True, linestyle='--', alpha=0.3)

    # 添加平均线
    avg_sales = daily_sales['总销量(千克)'].mean()
    ax.axhline(avg_sales, color='r', linestyle='--', linewidth=1.5,
               label=f'平均销量: {avg_sales:.1f}千克')

    # 添加图例
    ax.legend(fontsize=10, loc='upper right' if daily_sales['总销量(千克)'].max() > avg_sales else 'lower right')

    # 设置Y轴范围
    y_min = max(0, daily_sales['总销量(千克)'].min() * 0.9)
    y_max = daily_sales['总销量(千克)'].max() * 1.15
    ax.set_ylim(y_min, y_max)

# 添加整体标题
plt.suptitle('不同时期周销售量趋势对比', fontsize=18, y=0.98)

# 调整布局
plt.tight_layout(rect=[0, 0, 1, 0.96])  # 为总标题留出空间
plt.subplots_adjust(hspace=0.3, wspace=0.2)  # 增加子图间间距

# 保存图表
save_dir = 'E:/M/MathModel/23国赛C题/ds/销售分析图'
os.makedirs(save_dir, exist_ok=True)
save_path = os.path.join(save_dir, '四周销售量趋势对比.png')
plt.savefig(save_path, dpi=300, bbox_inches='tight')
print(f"\n图表已保存至: {save_path}")

plt.show()